package com.txzt.gaea.common.aspect;

import com.txzt.gaea.common.annotation.EntityCommonValue;
import com.txzt.gaea.common.core.base.context.AdminUserContext;
import com.txzt.gaea.common.enums.IsDeleteEnum;
import com.txzt.gaea.vo.AdminUserVO;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

@Aspect
@Component
public class ECVAspect {
    private static final String CREATEDDATE = "createTime";
    private static final String CREATEDPERSON = "createBy";
    private static final String UPDATEDDATE = "updateTime";
    private static final String UPDATEDPERSON = "updateBy";
    private static final String ISDELETE = "isDelete";
    private static final String DEPTID = "deptId";
    private static final Logger logger = LoggerFactory.getLogger(ECVAspect.class);

    @Pointcut("@annotation(com.txzt.gaea.common.annotation.EntityCommonValue)")
    public void operationPointCut() {
    }
    @Before("operationPointCut()")
    public void around(JoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        EntityCommonValue dal = method.getAnnotation(EntityCommonValue.class);
        if ("CREATE".equals(dal.operation())) {
            beforeInsert(point);
        } else if ("UPDATE".equals(dal.operation())){
            beforeUpdate(point);
        }
    }
    public void beforeInsert(JoinPoint point) {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        Object[] args = point.getArgs();
        if (args != null && args.length > 0) {
            Object argument = args[0];
            BeanWrapper beanWrapper = new BeanWrapperImpl(argument);
            //设置创建时间和修改时间
            if (beanWrapper.isWritableProperty(CREATEDDATE)) {
                beanWrapper.setPropertyValue(CREATEDDATE, new Date());
            }
            if (beanWrapper.isWritableProperty(UPDATEDDATE)) {
                beanWrapper.setPropertyValue(UPDATEDDATE, new Date());
            }
            if (null != adminUserVO) {
                //设置创建人和修改人
                if (beanWrapper.isWritableProperty(CREATEDPERSON) && null != adminUserVO.getId()) {
                    beanWrapper.setPropertyValue(CREATEDPERSON, adminUserVO.getId());
                }
                if (beanWrapper.isWritableProperty(UPDATEDPERSON) && null != adminUserVO.getId()) {
                    beanWrapper.setPropertyValue(UPDATEDPERSON, adminUserVO.getId());
                }
                if (beanWrapper.isWritableProperty(DEPTID)) {
                    beanWrapper.setPropertyValue(DEPTID, adminUserVO.getDeptid());
                }
            }
            //设置是否删除
            if (beanWrapper.isWritableProperty(ISDELETE)) {
                beanWrapper.setPropertyValue(ISDELETE, IsDeleteEnum.NOTDELETE.getCode());
            }
            logger.info("After insert = {}", ToStringBuilder.reflectionToString(argument, ToStringStyle.SHORT_PREFIX_STYLE));
        }
    }
    public void beforeUpdate(JoinPoint point) {
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        Object[] args = point.getArgs();
        if (args != null && args.length > 0) {
            Object argument = args[0];
            //如果参数是map类型
            if (argument instanceof Map) {
                Map map = (Map) argument;
                map.put(UPDATEDDATE, new Date());
                if (null != adminUserVO.getId()) {
                    map.put(UPDATEDPERSON, adminUserVO.getId());
                }
            } else {
                BeanWrapper beanWrapper = new BeanWrapperImpl(argument);
                //设置修改时间
                if (beanWrapper.isWritableProperty(UPDATEDDATE)) {
                    beanWrapper.setPropertyValue(UPDATEDDATE, new Date());
                }
                if (null != adminUserVO) {
                    //设置修改人
                    if (beanWrapper.isWritableProperty(UPDATEDPERSON) && null != adminUserVO.getId()) {
                        beanWrapper.setPropertyValue(UPDATEDPERSON, adminUserVO.getId());
                    }
                }
            }
            logger.info("After update = {}", ToStringBuilder.reflectionToString(argument, ToStringStyle.SHORT_PREFIX_STYLE));
        }
    }
}
